package com.rwy.web.task;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.google.api.client.util.Objects;
import com.rwy.dto.device.HandleFaultTaskDTO;
import com.rwy.service.HandleFaultDeviceService;
import com.rwy.util.CollectionUtil;
import com.rwy.util.CommonController;
import com.rwy.util.MessageStatusDTO;
import com.rwy.util.ObjectUtil;
import com.rwy.util.StringUtil;
import com.rwy.util.WXSendMessUtil;
import com.rwy.util.constant.CacheKeyEnum;
import com.rwy.util.constant.CacheValueKeyEnum;
import com.rwy.util.constant.FaultDeviceEnum;
import com.rwy.util.wxpojo.DepartmentVO;
import com.rwy.util.wxpojo.UserVO;
import com.rwy.web.filter.authorize.AuthorizeRespDTO;
import com.tool.http.httpclient.HttpClientUtil;
import com.tool.util.http.common.HttpConfig;

import lombok.extern.log4j.Log4j;

/** handle cron task class */
@Component
@Log4j
public class HandleCronTask extends CommonController {

	@Autowired
	HandleFaultDeviceService faultDeviceService;
	
	@Scheduled(cron ="0 */3 * * * *")
	public void createFaultTask()  {
		log.info("createFaultTask start..");
		faultDeviceService.createFaultTask();
		log.info(" createFaultTask end...");
	}
	
	@Scheduled(cron = "0 */4 * * * *")
	public void advicefaultTaskToEmployee()  throws Exception {
		log.info("advicefaultTaskToEmployee start..");
		List<HandleFaultTaskDTO> taskList = faultDeviceService.getWaitAdviceTask();
		if (!CollectionUtil.isEmpty(taskList)) {
			// mobile, adviceID 
			Map<String, List<Integer>> relationMap = taskList.stream().map(s ->HandleFaultTaskDTO.builder().mobile(s.getMobile()).adviceID(s.getAdviceID()).build()).collect(Collectors.groupingBy(HandleFaultTaskDTO::getMobile, Collectors.mapping(HandleFaultTaskDTO::getAdviceID, Collectors.toList())));
			Set<String> mobile = relationMap.keySet();
			String[] idArr = fault_handle_advice_department.split(",");
			if(!CollectionUtil.isEmpty(mobile)) {
				bathAdviceMethod(relationMap, getCommonAccessToken().getAccess_token(), new ArrayList<>(mobile), idArr);
			}
		}
		
		log.info("advicefaultTaskToEmployee end...");
	}
	
	/** 同步正常状态,关闭任务 complete  */
	@Scheduled(cron = "0 */10 * * * *")
	public void syncTerminalStatus() {
		faultDeviceService.syncNormalTerminalStatus();
	}
	
	
	@SuppressWarnings("unchecked")
	private void bathAdviceMethod(Map<String, List<Integer>> relationMap, String accesss_token, List<String> moibles,  String... arr) throws Exception{
		List<String> hadAdvice = new ArrayList<>();
		List<UserVO> userList = (List<UserVO>) getUserUserCacheValue(CacheValueKeyEnum.department_user_collect.getKey());
		if (CollectionUtil.isEmpty(userList)) {
			userList = new ArrayList<>();
			for(int i =0 ; i< arr.length ; i++) {
				String url = get_department_user_lsit_url.replace("access_token_value", accesss_token);
				url+= arr[i];
				String userInfo = HttpClientUtil.get(HttpConfig.custom().url(url));
				DepartmentVO  depart = JSON.parseObject(userInfo, DepartmentVO.class);
				if(depart != null && depart.getErrcode() == 0) {
					userList.addAll(depart.getUserlist());
				}
			}
			if (!CollectionUtil.isEmpty(userList)) {
				addCache(CacheKeyEnum.user.getKey(), CacheValueKeyEnum.department_user_collect.getKey(), userList);
			}
		}
		
		if (!CollectionUtil.isEmpty(userList)) {
			userList.stream().filter(s -> s.getMobile() != null && moibles.contains(s.getMobile())).forEach(s -> {
				hadAdvice.add(s.getMobile());
				adviceEmployee(s.getUserid(), s.getName(), relationMap.get(s.getMobile()));
			});
		}
		
		moibles.forEach(s -> {
			 if (!hadAdvice.contains(s)) {
				 faultDeviceService.updateHandleAdvice(HandleFaultTaskDTO.builder().ids(relationMap.get(s))
						 .adviceStatus(FaultDeviceEnum.advice_fail_task.getId())
						 .remark(Objects.equal(s, "0000")? "线下员工和 线上员工没有关联, 请核对. ":"线下员工通过手机号没有匹配到线上员工, 请核对.")
						 .build());
			 }
		});;
		
	}
	
	private void adviceEmployee(String userid, String name,  List<Integer> relationMap) {
		MessageStatusDTO json = null;
		try {
			json = WXSendMessUtil.Send_msg(getAppAccessToken().getAccess_token(), userid, "", "", "text", fault_handle_agentid, name + ", "+ fault_handle_advice_message);
		} catch (Exception e) {
			e.printStackTrace();
		}
		HandleFaultTaskDTO task = HandleFaultTaskDTO.builder().ids(relationMap).build();
		if (json != null && json.getErrcode() == 0) {
			task.setAdviceMess( name + ", "+ fault_handle_advice_message);
			task.setAdviceStatus(FaultDeviceEnum.advice_processed_task.getId());
		} else {
			task.setAdviceStatus(FaultDeviceEnum.advice_fail_task.getId());
			task.setRemark("通知消息出错."+json.getErrmsg());
		}
		faultDeviceService.updateHandleAdvice(task);
	}
	
	/** 获取应用AccessToken*/
	private AuthorizeRespDTO getAppAccessToken() throws Exception {
		AuthorizeRespDTO tokenDto = getCache(CacheKeyEnum.access_token.getKey(), CacheValueKeyEnum.cache_fault_device_key.getKey(), AuthorizeRespDTO.class);
		if (ObjectUtil.isEmpty(tokenDto)) {
			 String data = HttpClientUtil.get(HttpConfig.custom().url(fault_handle_login_get_token));
			 tokenDto = JSON.parseObject(data, AuthorizeRespDTO.class);
		     
			 if (ObjectUtil.isEmpty(tokenDto) || StringUtil.isEmpty(tokenDto.getAccess_token())) {
		    	 tokenDto = null;
		    	 log.error("get access token fail .." + data);
		     } else {
		    	 addCache(CacheKeyEnum.access_token.getKey(), CacheValueKeyEnum.cache_fault_device_key.getKey(), tokenDto);
		     }
		}
		return tokenDto;
	} 
	
}
